/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "NgUtil.h"

#include "OgreResourceGroupManager.h"
#include "OgrePlatform.h"
#include "OgreImage.h"
#include "OgreColourValue.h"
#include "OgreMath.h"

namespace PQEngine
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	const Ogre::String GPath::SEPERATOR= "\\";
#else
	const Ogre::String GPath::SEPERATOR= "/";
#endif

	GPath::GPath()
	{
	}

	GPath::GPath(const Ogre::String& file)
	{
	}

	GPath::GPath(const char* file)
		: _path(file)
	{
	}

	GPath::~GPath()
	{
	}

	const Ogre::String& GPath::getPath(void) const
	{
		return _path;
	}

	Ogre::String GPath::getAbsPath(void) const
	{
		return "";
	}

	// file access
	void GPath::getAsString(Ogre::String &dest) const
	{
	}

	Ogre::String GPath::getAsString(void) const
	{
		return "";
	}

	Ogre::String GPath::directory(void) const
	{
		return "";
	}

	Ogre::String GPath::base(void) const
	{
		normalizePlatform();

		Ogre::StringVector vec;
		vec= Ogre::StringUtil::split(_path, SEPERATOR);
		if (vec.empty()){
			return Ogre::StringUtil::BLANK;
		}
		return vec.at(vec.size() - 1);
	}

	Ogre::String GPath::extension(void) const
	{
		return "";
	}

	// seperator '/'
	void	GPath::normalize(void) const
	{
	}

	/// normalize based on platform seperator
	void	GPath::normalizePlatform(void) const
	{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
		Ogre::StringUtil::replaceAll(_path, "/", "\\");
#else
		Ogre::StringUtil::replaceAll(_path, "\\\\", "/");
#endif
	}

	int GPath::getFileSize(void) const
	{
		return 0;
	}
	void GPath::append(const Ogre::String &v)
	{
	}

	bool GPath::isAbs(void) const
	{
		return false;
	}
	bool GPath::isRel(void) const
	{
		return false;
	}

	bool GPath::exists(void) const
	{
		return false;
	}
	bool GPath::isFile(void) const
	{
		return false;
	}
	bool GPath::isDir(void) const
	{
		return false;
	}

	void GPath::split(Ogre::StringVector &arr) const
	{
	}

	bool NgUtil::isResource(const Ogre::String &name, const Ogre::String &group)
	{
		if (group.empty()){
			return Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(name);
		}	
		return Ogre::ResourceGroupManager::getSingleton().resourceExists(group, name);
	}


	Ogre::ColourValue NgUtil::getInterpolatedColor(float fx, float fy, Ogre::Image *img, bool wrapX)
    {
	    // Don't -> all the time, and avoid unsigned warnings
        int imgWidth = static_cast<int>(img->getWidth ());
        int imgHeight = static_cast<int>(img->getHeight ());

	    // Calculate pixel y coord.
        int py = Ogre::Math::IFloor(Ogre::Math::Abs (fy) * (imgHeight - 1));
        // Snap to py image bounds.
        py = std::max(0, std::min(py, imgHeight - 1));

	    // Get the two closest pixels on x.
        // px1 and px2 are the closest integer pixels to px.
        float px = fx * (img->getWidth () - 1);
	    int px1, px2;
        px1 = Ogre::Math::IFloor(px);
        px2 = Ogre::Math::ICeil(px);

        if (wrapX) {
            // Wrap x coords. The funny addition ensures that it does
            // "the right thing" for negative values.
            px1 = (px1 % imgWidth + imgWidth) % imgWidth;
            px2 = (px2 % imgWidth + imgWidth) % imgWidth;
        } else {
            px1 = std::max(0, std::min(px1, imgWidth - 1));
            px2 = std::max(0, std::min(px2, imgWidth - 1));
        }

	    // Calculate the interpolated pixel
	    Ogre::ColourValue c1, c2, cf;
        c1 = img->getColourAt (px1, py, 0);
        c2 = img->getColourAt (px2, py, 0);

        // Blend the two pixels together.
        // diff is the weight between pixel 1 and pixel 2.
        float diff = px - px1;
	    cf = c1 * (1 - diff) + c2 * diff;

	    return cf;
    }

}

